<template>
  <div class="log-list-container">
    <!-- 页面头部 -->
    <div class="page-header">
      <div class="page-title">
        <div class="title-with-back">
          <el-button 
            type="primary" 
            :icon="ArrowLeft" 
            @click="goBack"
            class="blue-return-button"
            circle
          />
          <div class="title-content">
            <div class="title-main">
              <el-icon class="title-icon"><FolderOpened /></el-icon>
              <h2>MinIO 审计日志列表</h2>
            </div>
            <p class="page-description">
              <el-icon><DataLine /></el-icon>
              <span>查询和浏览所有 MinIO S3 存储操作日志，追踪文件访问记录</span>
            </p>
          </div>
        </div>
      </div>
      
      <div class="page-stats">
        <div class="stat-card total">
          <div class="stat-icon">
            <el-icon><Menu /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ total }}</div>
            <div class="stat-label">查询结果</div>
            <div class="stat-trend">
              <el-icon><Menu /></el-icon>
              <span>总计</span>
            </div>
          </div>
        </div>
        
        <div class="stat-card get">
          <div class="stat-icon">
            <el-icon><Download /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ getCount }}</div>
            <div class="stat-label">读取</div>
            <div class="stat-trend">
              <el-icon><Download /></el-icon>
              <span>{{ getRate }}%</span>
            </div>
          </div>
        </div>
        
        <div class="stat-card put">
          <div class="stat-icon">
            <el-icon><Upload /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ putCount }}</div>
            <div class="stat-label">写入</div>
            <div class="stat-trend">
              <el-icon><Upload /></el-icon>
              <span>{{ putRate }}%</span>
            </div>
          </div>
        </div>
        
        <div class="stat-card slow">
          <div class="stat-icon">
            <el-icon><Timer /></el-icon>
          </div>
          <div class="stat-content">
            <div class="stat-number">{{ slowCount }}</div>
            <div class="stat-label">慢响应</div>
            <div class="stat-trend">
              <el-icon><Timer /></el-icon>
              <span>>1s</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 搜索和筛选区域 -->
    <div class="search-section">
      <el-card shadow="hover" class="search-card">
        <template #header>
          <div class="search-header">
            <div class="search-title">
              <el-icon><Search /></el-icon>
              <span>搜索与筛选</span>
            </div>
          </div>
        </template>
        
        <el-form :model="filterForm" class="search-form">
          <div class="search-form-content">
            <div class="search-form-fields">
              <el-form-item label="API类型">
                <el-select 
                  v-model="filterForm.api" 
                  placeholder="选择API类型" 
                  clearable
                  style="width: 180px"
                >
                  <el-option label="全部" value="" />
                  <el-option label="GetObject" value="GetObject" />
                  <el-option label="PutObject" value="PutObject" />
                  <el-option label="DeleteObject" value="DeleteObject" />
                  <el-option label="ListBucket" value="ListBucket" />
                  <el-option label="HeadObject" value="HeadObject" />
                </el-select>
              </el-form-item>

              <el-form-item label="存储桶">
                <el-input 
                  v-model="filterForm.bucket" 
                  placeholder="请输入存储桶名称" 
                  clearable
                  style="width: 180px"
                />
              </el-form-item>
            </div>
            
            <div class="search-form-actions">
              <el-button 
                @click="filterExpanded = !filterExpanded"
              >
                <el-icon>
                  <component :is="filterExpanded ? 'ArrowUp' : 'ArrowDown'" />
                </el-icon>
                {{ filterExpanded ? '收起筛选' : '高级筛选' }}
              </el-button>
              <el-button type="primary" @click="handleSearch" :icon="Search" class="search-btn">
                搜索
              </el-button>
              <el-button type="warning" @click="handleReset" :icon="Refresh" class="reset-btn">
                重置
              </el-button>
              <el-button type="info" @click="showFieldSelector = !showFieldSelector" class="field-btn">
                <el-icon><Setting /></el-icon>
                字段设置
              </el-button>
            </div>
          </div>

          <!-- 展开的筛选条件 -->
          <transition name="filter-expand">
            <div v-show="filterExpanded" class="search-form-expanded">
              <div class="search-form-fields">
                <el-form-item label="时间范围">
                  <el-date-picker
                    v-model="filterForm.timeRange"
                    type="datetimerange"
                    range-separator="至"
                    start-placeholder="开始时间"
                    end-placeholder="结束时间"
                    :shortcuts="dateShortcuts"
                    format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss"
                    style="width: 400px"
                    :teleported="true"
                    popper-class="datetime-picker-popper"
                    :clearable="true"
                  />
                </el-form-item>

                <el-form-item label="对象键">
                  <el-input 
                    v-model="filterForm.objectKey" 
                    placeholder="请输入对象键" 
                    clearable
                    style="width: 200px"
                  />
                </el-form-item>

                <el-form-item label="状态码">
                  <el-input 
                    v-model="filterForm.statusCode" 
                    placeholder="如: 200" 
                    clearable
                    style="width: 120px"
                  />
                </el-form-item>
              </div>
            </div>
          </transition>
        </el-form>
        
        <!-- 字段设置面板 -->
        <transition name="field-panel">
          <div v-if="showFieldSelector" class="field-selector-panel">
            <div class="field-sorter">
              <div class="sorter-header">
                <h4>字段排序设置</h4>
                <p class="sorter-description">使用上下箭头调整字段显示顺序，勾选要显示的字段</p>
              </div>
              <div class="field-list-sortable">
                <div
                  v-for="(field, index) in sortedFields"
                  :key="field.value"
                  class="field-item"
                  :class="{ 'field-disabled': !selectedFields.includes(field.value) }"
                >
                  <div class="field-drag-handle">
                    <span class="drag-icon">⋮⋮</span>
                  </div>
                  <el-checkbox
                    v-model="selectedFields"
                    :label="field.value"
                    :disabled="field.required"
                    class="field-checkbox"
                  >
                    <span class="field-label">{{ field.label }}</span>
                    <span v-if="field.required" class="required-mark">*</span>
                  </el-checkbox>
                  <div class="field-sort-controls">
                    <el-button
                      size="small"
                      :disabled="index === 0"
                      @click="moveFieldUp(index)"
                      circle
                      type="primary"
                      plain
                    >
                      ↑
                    </el-button>
                    <el-button
                      size="small"
                      :disabled="index === sortedFields.length - 1"
                      @click="moveFieldDown(index)"
                      circle
                      type="primary"
                      plain
                    >
                      ↓
                    </el-button>
                  </div>
                </div>
              </div>
            </div>
            
            <!-- 字段设置操作按钮 -->
            <div class="field-actions">
              <el-button type="primary" @click="saveCurrentFieldSettings">
                <el-icon><Check /></el-icon>
                保存设置
              </el-button>
              <el-button type="success" @click="setAsDefaultSettings">
                <el-icon><Star /></el-icon>
                设为默认
              </el-button>
              <el-button @click="resetFieldSettings">
                <el-icon><Refresh /></el-icon>
                重置默认
              </el-button>
              <el-button type="warning" @click="clearDefaultSettings">
                <el-icon><Delete /></el-icon>
                清除默认
              </el-button>
              <el-button @click="showFieldSelector = false">
                <el-icon><Close /></el-icon>
                关闭
              </el-button>
            </div>
          </div>
        </transition>
      </el-card>
    </div>

    <!-- 日志列表 -->
    <div class="table-section">
      <el-card shadow="hover" class="table-card">
        <template #header>
          <div class="table-header">
            <div class="table-title">
              <el-icon><List /></el-icon>
              <span>审计日志列表</span>
            </div>
            <div class="table-header-actions">
              <el-button 
                type="success" 
                @click="handleRefresh" 
                :icon="Refresh"
                :loading="loading" 
                size="small"
              >
                刷新
              </el-button>
              <div class="table-info">
                <!-- 合并的分页信息控制 -->
                <div class="pagination-control-wrapper" @click="paginationExpanded = !paginationExpanded">
                  <span class="page-count">本页 {{ logList.length }} 条</span>
                  <div class="divider"></div>
                  <span class="pagination-info">{{ pagination.page }}/{{ Math.ceil(total / pagination.pageSize) || 1 }}</span>
                  <el-icon class="pagination-icon" :class="{ 'expanded': paginationExpanded }">
                    <ArrowDown />
                  </el-icon>
                </div>
              </div>
            </div>
          </div>
        </template>
        
        <div class="table-container">
          <el-table
            v-loading="loading"
            :data="logList"
            :default-sort="{ prop: 'event_time', order: 'descending' }"
            @sort-change="handleSortChange"
            style="width: 100%;"
            :height="600"
            class="enhanced-table"
          >
            <template v-for="field in sortedFields" :key="field.value">
              <el-table-column
                v-if="selectedFields.includes(field.value)"
                :prop="field.value"
                :label="field.label"
                :width="field.width"
                :fixed="field.value === 'event_time' ? 'left' : false"
                :sortable="field.value === 'event_time' ? 'custom' : false"
                :sort-orders="['descending', 'ascending', null]"
                show-overflow-tooltip
              >
                <template #default="{ row }">
                  <!-- 时间 - 后端已格式化到秒 -->
                  <span v-if="field.value === 'event_time'">{{ row.event_time }}</span>
                  <!-- API类型 - 可复制 -->
                  <div v-else-if="field.value === 'api'" class="json-cell">
                    <el-tag size="small" :type="getApiType(row.api)">{{ row.api }}</el-tag>
                    <el-button
                      v-if="row.api"
                      size="small"
                      text
                      type="primary"
                      @click.stop="copyToClipboard(row.api)"
                      :icon="CopyDocument"
                      class="copy-btn"
                      title="复制API类型"
                    />
                  </div>
                  <!-- 存储桶 - 可复制 -->
                  <div v-else-if="field.value === 'bucket'" class="json-cell">
                    <span class="json-text">{{ row.bucket }}</span>
                    <el-button
                      v-if="row.bucket"
                      size="small"
                      text
                      type="primary"
                      @click.stop="copyToClipboard(row.bucket)"
                      :icon="CopyDocument"
                      class="copy-btn"
                      title="复制存储桶"
                    />
                  </div>
                  <!-- 对象键 - 可复制、可预览图片 -->
                  <div v-else-if="field.value === 'object_key'" class="json-cell">
                    <span class="json-text">{{ row.object_key }}</span>
                    <div class="action-icons">
                      <el-button
                        v-if="row.object_key && row.bucket && isImageFile(row.object_key)"
                        size="small"
                        text
                        type="success"
                        @click.stop="previewImage(row.bucket, row.object_key)"
                        :icon="View"
                        class="copy-btn"
                        title="预览图片"
                      />
                      <el-button
                        v-if="row.object_key"
                        size="small"
                        text
                        type="primary"
                        @click.stop="copyToClipboard(row.object_key)"
                        :icon="CopyDocument"
                        class="copy-btn"
                        title="复制对象键"
                      />
                    </div>
                  </div>
                  <!-- 状态码 -->
                  <el-tag v-else-if="field.value === 'status_code'" size="small" :type="getStatusType(row.status_code)">{{ row.status_code }}</el-tag>
                  <!-- 接收字节 -->
                  <span v-else-if="field.value === 'rx_bytes'">{{ formatBytes(row.rx_bytes) }}</span>
                  <!-- 发送字节 -->
                  <span v-else-if="field.value === 'tx_bytes'">{{ formatBytes(row.tx_bytes) }}</span>
                  <!-- 响应时间 -->
                  <span v-else-if="field.value === 'time_to_response'" :class="{ 'slow-response': row.time_to_response > 1000000 }">{{ formatTime(row.time_to_response) }}</span>
                  <!-- 远程主机 -->
                  <span v-else-if="field.value === 'remote_host'">{{ row.remote_host || '-' }}</span>
                  <!-- 请求ID - 可复制 -->
                  <div v-else-if="field.value === 'request_id'" class="json-cell">
                    <span class="json-text">{{ row.request_id || '-' }}</span>
                    <el-button
                      v-if="row.request_id"
                      size="small"
                      text
                      type="primary"
                      @click.stop="copyToClipboard(row.request_id)"
                      :icon="CopyDocument"
                      class="copy-btn"
                      title="复制请求ID"
                    />
                  </div>
                  <!-- User Agent -->
                  <span v-else-if="field.value === 'user_agent'">{{ row.user_agent || '-' }}</span>
                  <!-- 版本 -->
                  <span v-else-if="field.value === 'version'">{{ row.version || '-' }}</span>
                  <!-- 部署ID -->
                  <span v-else-if="field.value === 'deployment_id'">{{ row.deployment_id || '-' }}</span>
                  <!-- API状态 -->
                  <el-tag v-else-if="field.value === 'api_status'" size="small" type="success">{{ row.api_status || '-' }}</el-tag>
                  <!-- 响应头字节 -->
                  <span v-else-if="field.value === 'tx_headers'">{{ formatBytes(row.tx_headers || 0) }}</span>
                  <!-- 事件类型 -->
                  <span v-else-if="field.value === 'event'">{{ row.event || '-' }}</span>
                  <!-- 触发来源 -->
                  <span v-else-if="field.value === 'trigger'">{{ row.trigger || '-' }}</span>
                  <!-- JSON字段 (请求头、响应头、标签) - 显示缩略内容 + 复制按钮 -->
                  <div v-else-if="['request_header', 'response_header', 'tags'].includes(field.value)" class="json-cell">
                    <span class="json-text">{{ formatJsonString(row[field.value], 0) }}</span>
                    <el-button
                      v-if="row[field.value]"
                      size="small"
                      text
                      type="primary"
                      @click.stop="copyToClipboard(getRawJsonValue(row[field.value]))"
                      :icon="CopyDocument"
                      class="copy-btn"
                      title="复制"
                    />
                  </div>
                  <!-- 访问密钥 -->
                  <span v-else-if="field.value === 'access_key'">{{ row.access_key || '-' }}</span>
                  <!-- 父用户 -->
                  <span v-else-if="field.value === 'parent_user'">{{ row.parent_user || '-' }}</span>
                  <!-- 默认 -->
                  <span v-else>{{ row[field.value] || '-' }}</span>
                </template>
              </el-table-column>
            </template>

            <!-- 操作列固定 -->
            <el-table-column label="操作" width="80" fixed="right">
              <template #default="{ row }">
                <div class="action-buttons">
                  <el-tooltip content="查看详情" placement="top">
                    <el-button 
                      type="primary"
                      size="small" 
                      @click="viewDetail(row)" 
                      circle
                    >
                      <el-icon><View /></el-icon>
                    </el-button>
                  </el-tooltip>
                </div>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <!-- 可折叠分页 -->
        <div v-show="paginationExpanded" class="pagination">
          <el-pagination
            v-model:current-page="pagination.page"
            v-model:page-size="pagination.pageSize"
            :page-sizes="[20, 50, 100, 200]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handlePageChange"
            class="enhanced-pagination"
          />
        </div>
      </el-card>
    </div>

    <!-- 详情弹窗 -->
    <el-dialog
      v-model="detailDialogVisible"
      width="900px"
      :close-on-click-modal="false"
      top="5vh"
      class="unified-dialog"
    >
      <template #header>
        <div class="dialog-header">
          <div class="header-icon header-icon-primary">
            <el-icon><Document /></el-icon>
          </div>
          <div class="header-content">
            <h3>日志详情</h3>
            <p>查看Minio审计日志详细信息</p>
          </div>
        </div>
      </template>
      
      <div v-if="selectedLog" class="dialog-content">
        <el-descriptions :column="2" border size="default">
          <el-descriptions-item label="时间" label-class-name="detail-label">
            {{ selectedLog.event_time }}
          </el-descriptions-item>
          <el-descriptions-item label="API类型" label-class-name="detail-label">
            <el-tag size="small" :type="getApiType(selectedLog.api)">
              {{ selectedLog.api }}
            </el-tag>
          </el-descriptions-item>
          
          <el-descriptions-item label="存储桶" label-class-name="detail-label">
            <el-tag size="small" type="info">{{ selectedLog.bucket }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="状态码" label-class-name="detail-label">
            <el-tag size="small" :type="selectedLog.status_code === 200 ? 'success' : 'danger'">
              {{ selectedLog.status_code }}
            </el-tag>
          </el-descriptions-item>
          
          <el-descriptions-item label="对象键" :span="2" label-class-name="detail-label">
            <div class="detail-text">{{ selectedLog.object_key }}</div>
          </el-descriptions-item>
          
          <el-descriptions-item label="接收字节" label-class-name="detail-label">
            {{ formatBytes(selectedLog.rx_bytes) }}
          </el-descriptions-item>
          <el-descriptions-item label="发送字节" label-class-name="detail-label">
            {{ formatBytes(selectedLog.tx_bytes) }}
          </el-descriptions-item>
          
          <el-descriptions-item label="响应时间" label-class-name="detail-label">
            <span :class="{ 'slow-response': selectedLog.time_to_response > 1000000 }">
              {{ formatTime(selectedLog.time_to_response) }}
            </span>
          </el-descriptions-item>
          <el-descriptions-item label="请求ID" label-class-name="detail-label">
            <div class="detail-text">{{ selectedLog.request_id }}</div>
          </el-descriptions-item>
          
          <el-descriptions-item label="远程主机" label-class-name="detail-label">
            {{ selectedLog.remote_host }}
          </el-descriptions-item>
          <el-descriptions-item label="事件" label-class-name="detail-label">
            {{ selectedLog.event || '-' }}
          </el-descriptions-item>
          
          <el-descriptions-item label="触发源" label-class-name="detail-label">
            {{ selectedLog.trigger || '-' }}
          </el-descriptions-item>
          <el-descriptions-item label="API状态" label-class-name="detail-label">
            <el-tag v-if="selectedLog.api_status" size="small" type="success">
              {{ selectedLog.api_status }}
            </el-tag>
            <span v-else>-</span>
          </el-descriptions-item>
          
          <el-descriptions-item label="User Agent" :span="2" label-class-name="detail-label">
            <div class="detail-message">{{ selectedLog.user_agent || '-' }}</div>
          </el-descriptions-item>
          
          <el-descriptions-item label="请求头" :span="2" label-class-name="detail-label">
            <div class="detail-json">
              <el-button 
                v-if="selectedLog.request_header"
                size="small" 
                text 
                type="primary"
                @click="copyToClipboard(getRawJsonValue(selectedLog.request_header))"
                :icon="CopyDocument"
                style="float: right;"
              >
                复制
              </el-button>
              <pre v-if="selectedLog.request_header" class="json-content">{{ formatJsonString(selectedLog.request_header) }}</pre>
              <span v-else>-</span>
            </div>
          </el-descriptions-item>
          
          <el-descriptions-item label="响应头" :span="2" label-class-name="detail-label">
            <div class="detail-json">
              <el-button 
                v-if="selectedLog.response_header"
                size="small" 
                text 
                type="primary"
                @click="copyToClipboard(getRawJsonValue(selectedLog.response_header))"
                :icon="CopyDocument"
                style="float: right;"
              >
                复制
              </el-button>
              <pre v-if="selectedLog.response_header" class="json-content">{{ formatJsonString(selectedLog.response_header) }}</pre>
              <span v-else>-</span>
            </div>
          </el-descriptions-item>
        </el-descriptions>
      </div>
      
      <template #footer>
        <el-button @click="detailDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>

    <!-- 图片预览弹窗 -->
    <el-dialog
      v-model="imagePreviewVisible"
      width="60%"
      :close-on-click-modal="true"
      top="8vh"
      class="unified-dialog image-preview-dialog"
    >
      <template #header>
        <div class="dialog-header">
          <div class="header-icon header-icon-success">
            <el-icon><Picture /></el-icon>
          </div>
          <div class="header-content">
            <h3>图片预览</h3>
            <p>{{ previewImageUrl }}</p>
          </div>
        </div>
      </template>
      
      <div class="image-preview-container">
        <el-image
          :src="previewImageUrl"
          fit="contain"
          style="width: 100%; height: 100%;"
          :preview-src-list="[previewImageUrl]"
          :initial-index="0"
          :preview-teleported="true"
        >
          <template #error>
            <div class="image-error">
              <el-icon class="error-icon"><Picture /></el-icon>
              <p>图片加载失败</p>
              <p class="error-url">{{ previewImageUrl }}</p>
            </div>
          </template>
        </el-image>
      </div>
      
      <template #footer>
        <div class="image-preview-footer">
          <el-button 
            type="primary" 
            @click="copyToClipboard(previewImageUrl, '图片链接')"
            :icon="CopyDocument"
          >
            复制链接
          </el-button>
          <el-button @click="imagePreviewVisible = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { 
  ArrowLeft, Refresh, Search, FolderOpened, DataLine, 
  Clock, Filter, Connection, Download, Upload, Timer, Menu, 
  List, View, ArrowDown, ArrowUp, Setting, Star, Delete, Close, Check, CopyDocument, Picture, Document
} from '@element-plus/icons-vue'
import api from '@/utils/api'
import { componentLogger } from '@/utils/logger'
import { copyToClipboard as copyTextUtil } from '@/utils/clipboard'

const router = useRouter()

// 状态
const loading = ref(false)
const logList = ref([])
const total = ref(0)
const detailDialogVisible = ref(false)
const selectedLog = ref(null)
const filterExpanded = ref(false) // 筛选区域展开状态
const paginationExpanded = ref(false) // 分页区域展开状态
const showFieldSelector = ref(false) // 字段选择器显示状态
const imagePreviewVisible = ref(false) // 图片预览对话框
const previewImageUrl = ref('') // 预览图片URL

// Minio配置 - TODO: 后续可从后端获取
const MINIO_HOST = 'http://183.6.4.235:9000'

// 字段定义
const allFields = [
  { label: '时间', value: 'event_time', required: true, width: '180', group: 'basic' },
  { label: '版本', value: 'version', required: false, width: '100', group: 'basic' },
  { label: '部署ID', value: 'deployment_id', required: false, width: '200', group: 'basic' },
  { label: 'API类型', value: 'api', required: false, width: '140', group: 'basic' },
  { label: '存储桶', value: 'bucket', required: false, width: '120', group: 'basic' },
  { label: '对象键', value: 'object_key', required: false, width: '300', group: 'basic' },
  { label: '状态码', value: 'status_code', required: false, width: '100', group: 'basic' },
  { label: 'API状态', value: 'api_status', required: false, width: '100', group: 'basic' },
  { label: '接收字节', value: 'rx_bytes', required: false, width: '120', group: 'traffic' },
  { label: '发送字节', value: 'tx_bytes', required: false, width: '120', group: 'traffic' },
  { label: '响应头字节', value: 'tx_headers', required: false, width: '120', group: 'traffic' },
  { label: '响应时间', value: 'time_to_response', required: false, width: '120', group: 'performance' },
  { label: '远程主机', value: 'remote_host', required: false, width: '140', group: 'network' },
  { label: '请求ID', value: 'request_id', required: false, width: '180', group: 'network' },
  { label: 'User Agent', value: 'user_agent', required: false, width: '200', group: 'network' },
  { label: '事件类型', value: 'event', required: false, width: '120', group: 'event' },
  { label: '触发来源', value: 'trigger', required: false, width: '120', group: 'event' },
  { label: '请求头', value: 'request_header', required: false, width: '150', group: 'data' },
  { label: '响应头', value: 'response_header', required: false, width: '150', group: 'data' },
  { label: '标签', value: 'tags', required: false, width: '150', group: 'data' },
  { label: '访问密钥', value: 'access_key', required: false, width: '200', group: 'security' },
  { label: '父用户', value: 'parent_user', required: false, width: '150', group: 'security' }
]

// 字段排序和选择状态
const sortedFields = ref([...allFields])
// 默认只显示修改前的基础字段 + 重要的 JSON 字段
const defaultSelectedFields = [
  'event_time',
  'api',
  'bucket',
  'object_key',
  'status_code',
  'rx_bytes',
  'tx_bytes',
  'time_to_response',
  'remote_host',
  'request_id',
  'request_header',
  'response_header'
]
const selectedFields = ref([...defaultSelectedFields])

// 从localStorage加载默认设置
const loadFieldSettings = () => {
  const saved = localStorage.getItem('minioAuditLogFields')
  if (saved) {
    try {
      const { sorted, selected } = JSON.parse(saved)
      if (sorted && selected && Array.isArray(sorted) && Array.isArray(selected)) {
        // 验证和修复字段数据
        // 1. 确保所有 allFields 中的字段都在 sorted 中
        const sortedValues = sorted.map(f => f.value)
        const missingFields = allFields.filter(f => !sortedValues.includes(f.value))
        
        if (missingFields.length > 0) {
          // 将缺失的字段添加到末尾
          sortedFields.value = [...sorted, ...missingFields]
          componentLogger.warn('检测到缺失字段，已自动添加', { missingFields: missingFields.map(f => f.value) })
        } else {
          sortedFields.value = sorted
        }
        
        // 2. 确保所有必需字段都在 selected 中
        const requiredFields = allFields.filter(f => f.required).map(f => f.value)
        const validSelected = [...new Set([...selected, ...requiredFields])]
        
        // 3. 移除 selected 中不存在的字段（可能是旧版本遗留）
        const allFieldValues = allFields.map(f => f.value)
        selectedFields.value = validSelected.filter(f => allFieldValues.includes(f))
        
        componentLogger.info('加载字段设置成功', { 
          sorted: sortedFields.value.length, 
          selected: selectedFields.value.length 
        })
      } else {
        componentLogger.warn('localStorage 数据格式不正确，使用默认设置')
      }
    } catch (e) {
      componentLogger.error('加载字段设置失败，使用默认设置', e)
      // 发生错误时，清除损坏的数据
      localStorage.removeItem('minioAuditLogFields')
    }
  }
}

// 分页
const pagination = reactive({
  page: 1,
  pageSize: 50
})

// 筛选表单
const filterForm = reactive({
  timeRange: [],
  api: '',
  bucket: '',
  objectKey: '',
  statusCode: ''
})

// 排序状态（默认按时间降序）
const sortField = ref('event_time')
const sortOrder = ref('desc')

// 设置默认时间范围：今天0点到当前时刻
const setDefaultTimeRange = () => {
  const now = new Date()
  const startOfToday = new Date()
  startOfToday.setHours(0, 0, 0, 0)
  
  // 格式化为 YYYY-MM-DD HH:mm:ss
  const formatDateTime = (date) => {
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    const hours = String(date.getHours()).padStart(2, '0')
    const minutes = String(date.getMinutes()).padStart(2, '0')
    const seconds = String(date.getSeconds()).padStart(2, '0')
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  }
  
  filterForm.timeRange = [formatDateTime(startOfToday), formatDateTime(now)]
}

// 时间快捷选项
const dateShortcuts = [
  {
    text: '最近1小时',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setHours(start.getHours() - 1)
      return [start, end]
    }
  },
  {
    text: '最近6小时',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setHours(start.getHours() - 6)
      return [start, end]
    }
  },
  {
    text: '今天',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setHours(0, 0, 0, 0)
      return [start, end]
    }
  },
  {
    text: '昨天',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setDate(start.getDate() - 1)
      start.setHours(0, 0, 0, 0)
      end.setDate(end.getDate() - 1)
      end.setHours(23, 59, 59, 999)
      return [start, end]
    }
  },
  {
    text: '最近7天',
    value: () => {
      const end = new Date()
      const start = new Date()
      start.setDate(start.getDate() - 7)
      return [start, end]
    }
  }
]

// 计算统计数据
// 全局统计数据（来自后端API）
const globalStats = ref({
  get_count: 0,
  put_count: 0,
  slow_count: 0
})

const getCount = computed(() => globalStats.value.get_count)
const putCount = computed(() => globalStats.value.put_count)
const slowCount = computed(() => globalStats.value.slow_count)

// 计算百分比
const getRate = computed(() => {
  if (total.value === 0) return 0
  return ((getCount.value / total.value) * 100).toFixed(1)
})

const putRate = computed(() => {
  if (total.value === 0) return 0
  return ((putCount.value / total.value) * 100).toFixed(1)
})

// 获取日志列表
const fetchLogs = async () => {
  try {
    loading.value = true
    componentLogger.info('开始获取Minio日志列表...')
    
    const filters = {}
    if (filterForm.timeRange && filterForm.timeRange.length === 2) {
      filters.start_time = filterForm.timeRange[0]
      filters.end_time = filterForm.timeRange[1]
    }
    if (filterForm.api) filters.api = filterForm.api
    if (filterForm.bucket) filters.bucket = filterForm.bucket
    if (filterForm.objectKey) filters.object_key = filterForm.objectKey
    if (filterForm.statusCode) filters.status_code = filterForm.statusCode
    
    componentLogger.info('请求参数', {
      filters,
      page: pagination.page,
      page_size: pagination.pageSize
    })
    
    const response = await api.get('/logs/minio/logs', {
      params: {
        ...filters,
        page: pagination.page,
        page_size: pagination.pageSize,
        sort: sortField.value,
        order: sortOrder.value
      }
    })
    
    componentLogger.info('API响应', response)
    
    if (response.data && response.data.success) {
      logList.value = response.data.data.logs
      total.value = response.data.data.total
      // 提取全局统计数据
      if (response.data.data.stats) {
        globalStats.value = response.data.data.stats
      }
      componentLogger.info('获取Minio日志列表成功', { 
        total: response.data.data.total,
        page: pagination.page,
        logsCount: response.data.data.logs ? response.data.data.logs.length : 0
      })
    } else {
      componentLogger.error('API返回失败', response)
    }
  } catch (error) {
    componentLogger.error('获取Minio日志列表失败', error)
    ElMessage.error('获取日志列表失败: ' + (error.message || '未知错误'))
  } finally {
    loading.value = false
  }
}

// 搜索
const handleSearch = () => {
  pagination.page = 1
  fetchLogs()
}

// 重置
const handleReset = () => {
  setDefaultTimeRange() // 重置到今天0点到当前时刻
  filterForm.api = ''
  filterForm.bucket = ''
  filterForm.objectKey = ''
  filterForm.statusCode = ''
  pagination.page = 1
  fetchLogs()
}

// 刷新
const handleRefresh = () => {
  // 如果有时间范围，更新结束时间到当前时刻
  if (filterForm.timeRange && filterForm.timeRange.length === 2) {
    const now = new Date()
    const year = now.getFullYear()
    const month = String(now.getMonth() + 1).padStart(2, '0')
    const day = String(now.getDate()).padStart(2, '0')
    const hours = String(now.getHours()).padStart(2, '0')
    const minutes = String(now.getMinutes()).padStart(2, '0')
    const seconds = String(now.getSeconds()).padStart(2, '0')
    filterForm.timeRange[1] = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  }
  fetchLogs()
}

// 分页改变
const handlePageChange = (page) => {
  pagination.page = page
  fetchLogs()
}

const handleSizeChange = (size) => {
  pagination.pageSize = size
  pagination.page = 1
  fetchLogs()
}

// 返回
const goBack = () => {
  router.back()
}

// 查看详情
const viewDetail = (row) => {
  selectedLog.value = row
  detailDialogVisible.value = true
}

// 通用复制到剪贴板 - 使用统一工具
const copyToClipboard = async (text, label = '内容') => {
  await copyTextUtil(text, label)
}

// 格式化字节
const formatBytes = (bytes) => {
  if (!bytes || bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}

// 格式化时间（纳秒）
const formatTime = (ns) => {
  if (!ns || ns === 0) return '0μs'
  if (ns < 1000) return ns + 'ns'
  if (ns < 1000000) return Math.round(ns / 1000) + 'μs'
  if (ns < 1000000000) return Math.round(ns / 1000000) + 'ms'
  return Math.round(ns / 1000000000 * 100) / 100 + 's'
}

// 获取API类型标签
const getApiType = (api) => {
  if (api && api.includes('Get')) return 'success'
  if (api && api.includes('Put')) return 'primary'
  if (api && api.includes('Delete')) return 'danger'
  if (api && api.includes('List')) return 'info'
  return ''
}

// 获取状态码标签类型
const getStatusType = (code) => {
  if (code >= 200 && code < 300) return 'success'
  if (code >= 400 && code < 500) return 'warning'
  if (code >= 500) return 'danger'
  return 'info'
}

// 格式化 JSON 字符串 - 处理转义的 JSON
const formatJsonString = (value, indent = 2) => {
  if (!value) return '-'
  
  try {
    let jsonObj = value
    
    // 如果是字符串，尝试解析
    if (typeof value === 'string') {
      // 尝试第一次解析 - 处理被字符串化的 JSON
      try {
        jsonObj = JSON.parse(value)
      } catch (e) {
        // 如果解析失败，可能是普通字符串，直接返回
        return value
      }
      
      // 如果解析后还是字符串，再尝试解析一次（处理双重字符串化的情况）
      if (typeof jsonObj === 'string') {
        try {
          jsonObj = JSON.parse(jsonObj)
        } catch (e) {
          // 如果还是失败，返回第一次解析的结果
          return jsonObj
        }
      }
    }
    
    // 格式化输出
    return JSON.stringify(jsonObj, null, indent)
  } catch (error) {
    componentLogger.warn('JSON格式化失败', { error: error.message, value })
    // 如果所有尝试都失败，返回原始值
    return typeof value === 'string' ? value : JSON.stringify(value)
  }
}

// 获取原始 JSON 值（用于复制）
const getRawJsonValue = (value) => {
  if (!value) return ''
  
  try {
    let jsonObj = value
    
    // 如果是字符串，尝试解析
    if (typeof value === 'string') {
      try {
        jsonObj = JSON.parse(value)
        // 如果解析后还是字符串，再尝试解析一次
        if (typeof jsonObj === 'string') {
          try {
            jsonObj = JSON.parse(jsonObj)
          } catch (e) {
            return jsonObj
          }
        }
      } catch (e) {
        return value
      }
    }
    
    return typeof jsonObj === 'string' ? jsonObj : JSON.stringify(jsonObj, null, 2)
  } catch (error) {
    return typeof value === 'string' ? value : JSON.stringify(value)
  }
}

// 判断是否为图片文件
const isImageFile = (objectKey) => {
  if (!objectKey) return false
  const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg', '.ico']
  const lowerKey = objectKey.toLowerCase()
  return imageExtensions.some(ext => lowerKey.endsWith(ext))
}

// 构建Minio访问URL
const buildMinioUrl = (bucket, objectKey) => {
  if (!bucket || !objectKey) return ''
  // URL格式: http://host:port/bucket/object_key
  return `${MINIO_HOST}/${bucket}/${objectKey}`
}

// 预览图片
const previewImage = (bucket, objectKey) => {
  if (!bucket || !objectKey) {
    ElMessage.warning('存储桶或对象键为空，无法预览')
    return
  }
  
  if (!isImageFile(objectKey)) {
    ElMessage.warning('该文件不是图片格式')
    return
  }
  
  previewImageUrl.value = buildMinioUrl(bucket, objectKey)
  imagePreviewVisible.value = true
  componentLogger.info('预览图片', { bucket, objectKey, url: previewImageUrl.value })
}

// 字段操作方法
const moveFieldUp = (index) => {
  if (index > 0) {
    const temp = sortedFields.value[index]
    sortedFields.value[index] = sortedFields.value[index - 1]
    sortedFields.value[index - 1] = temp
  }
}

const moveFieldDown = (index) => {
  if (index < sortedFields.value.length - 1) {
    const temp = sortedFields.value[index]
    sortedFields.value[index] = sortedFields.value[index + 1]
    sortedFields.value[index + 1] = temp
  }
}

const saveCurrentFieldSettings = () => {
  try {
    // 验证数据完整性
    if (!sortedFields.value || !selectedFields.value) {
      throw new Error('字段数据不完整')
    }
    
    // 确保所有必需字段都被选中
    const requiredFields = allFields.filter(f => f.required).map(f => f.value)
    const missingRequired = requiredFields.filter(f => !selectedFields.value.includes(f))
    
    if (missingRequired.length > 0) {
      // 自动添加必需字段
      selectedFields.value = [...selectedFields.value, ...missingRequired]
      ElMessage.warning('已自动添加必需字段')
    }
    
    localStorage.setItem('minioAuditLogFields', JSON.stringify({
      sorted: sortedFields.value,
      selected: selectedFields.value
    }))
    ElMessage.success('字段设置已保存')
    componentLogger.info('保存字段设置', { 
      sortedCount: sortedFields.value.length, 
      selectedCount: selectedFields.value.length 
    })
  } catch (error) {
    ElMessage.error('保存字段设置失败: ' + error.message)
    componentLogger.error('保存字段设置失败', error)
  }
}

const setAsDefaultSettings = () => {
  saveCurrentFieldSettings()
  ElMessage.success('已设为默认设置')
  componentLogger.info('设为默认字段设置')
}

const resetFieldSettings = () => {
  const saved = localStorage.getItem('minioAuditLogFields')
  if (saved) {
    const { sorted, selected } = JSON.parse(saved)
    sortedFields.value = [...sorted]
    selectedFields.value = [...selected]
    ElMessage.success('已重置为默认设置')
    componentLogger.info('重置字段设置')
  } else {
    ElMessage.warning('没有保存的默认设置')
  }
}

const clearDefaultSettings = () => {
  localStorage.removeItem('minioAuditLogFields')
  sortedFields.value = [...allFields]
  selectedFields.value = [...defaultSelectedFields]
  ElMessage.success('已清除默认设置，恢复为基础字段')
  componentLogger.info('清除默认字段设置')
}

// 处理排序变化
const handleSortChange = ({ prop, order }) => {
  if (!prop || !order) {
    // 取消排序，恢复默认（按时间降序）
    sortField.value = 'event_time'
    sortOrder.value = 'desc'
  } else {
    // 设置排序
    sortField.value = prop
    sortOrder.value = order === 'ascending' ? 'asc' : 'desc'
  }
  // 刷新数据
  fetchLogs()
}

// 初始化
onMounted(() => {
  setDefaultTimeRange() // 设置默认时间范围
  loadFieldSettings()
  fetchLogs()
  componentLogger.info('Minio审计日志列表页面已加载')
})
</script>

<style scoped>
/* 容器样式 */
.log-list-container {
  padding: 0;
  /* 统一使用纯灰色背景，与其他页面保持一致 */
  min-height: calc(100vh - 60px);
}

/* 页面头部布局 */
.title-with-back {
  display: flex;
  align-items: flex-start;
  gap: 15px;
}

.blue-return-button {
  background: linear-gradient(135deg, #409eff 0%, #66b3ff 100%);
  border: none;
  border-radius: 8px;
  padding: 8px 16px;
  font-weight: 500;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
  transition: all 0.3s ease;
  flex-shrink: 0;
  margin-top: 2px;
}

.blue-return-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(64, 158, 255, 0.4);
  background: linear-gradient(135deg, #66b3ff 0%, #409eff 100%);
}

.title-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* ===== 页面头部样式 ===== */
.page-header {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding: 20px 24px;
  border-radius: 12px;
  overflow: hidden;
  color: #303133;
  min-height: 120px;
  border: 1px solid #e4e7ed;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.page-title {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 12px;
  flex: 1;
}

.title-icon .icon-container {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

.title-icon .icon-container:hover {
  transform: scale(1.05);
}

.icon-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 100%;
  background: inherit;
  border-radius: inherit;
  filter: blur(12px);
  opacity: 0.5;
  z-index: -1;
}

.title-content {
  flex: 1;
}

.title-main {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}

.title-main h1 {
  font-size: 20px;
  font-weight: 600;
  color: #303133;
  margin: 0;
  letter-spacing: -0.3px;
}

.title-badge {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: #f0f9ff;
  border-radius: 12px;
  color: #67c23a;
  font-size: 12px;
  font-weight: 500;
}

.page-description {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: #606266;
  margin: 0 0 8px 0;
}

.title-meta {
  display: flex;
  gap: 16px;
  margin-top: 8px;
}

.meta-item {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #606266;
  padding: 3px 10px;
  background: #f5f7fa;
  border-radius: 8px;
}

/* 统计卡片 - 与 job 页面一致 */
.page-stats {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 20px;
}

.stat-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #e4e7ed;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  min-width: 120px;
  position: relative;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.stat-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.stat-card:hover {
  background: #fff;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  border-color: #409eff;
}

.stat-card:hover::before {
  opacity: 1;
}

.stat-icon {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  font-size: 16px;
  transition: all 0.3s ease;
}

.stat-card.get .stat-icon {
  background: rgba(103, 194, 58, 0.1);
  color: #67c23a;
}

.stat-card.put .stat-icon {
  background: rgba(64, 158, 255, 0.1);
  color: #409eff;
}

.stat-card.slow .stat-icon {
  background: rgba(230, 162, 60, 0.1);
  color: #e6a23c;
}

.stat-card.total .stat-icon {
  background: rgba(144, 147, 153, 0.1);
  color: #909399;
}

.stat-content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}

.stat-number {
  font-size: 20px;
  font-weight: 700;
  color: #303133;
  line-height: 1;
}

.stat-label {
  font-size: 12px;
  color: #909399;
  font-weight: 500;
}

.stat-trend {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #c0c4cc;
  font-weight: 500;
}

/* ===== 搜索卡片样式 ===== */
.search-section {
  margin-bottom: 24px;
}

.search-card {
  border-radius: 16px;
  border: none;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
}

.search-card:hover {
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}

.search-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.search-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.search-title .el-icon {
  color: #409eff;
}

.search-form-content {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 20px;
}

.search-form-fields {
  display: flex;
  gap: 16px;
  flex: 1;
}

.search-form-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.search-form-expanded {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #e4e7ed;
}

/* 折叠展开动画 */
.filter-expand-enter-active,
.filter-expand-leave-active {
  transition: all 0.3s ease;
  overflow: hidden;
}

.filter-expand-enter-from,
.filter-expand-leave-to {
  opacity: 0;
  max-height: 0;
  margin-top: 0;
  padding-top: 0;
}

.filter-expand-enter-to,
.filter-expand-leave-from {
  opacity: 1;
  max-height: 500px;
  margin-top: 16px;
  padding-top: 16px;
}

/* ===== 表格卡片样式 ===== */
.table-section {
  margin-bottom: 24px;
}

.table-card {
  border-radius: 16px;
  border: none;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
}

.table-card:hover {
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
}

.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.table-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.table-title .el-icon {
  color: #409eff;
}

.table-header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.table-info {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pagination-control-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  background: rgba(64, 158, 255, 0.08);
  border: 1px solid rgba(64, 158, 255, 0.2);
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  user-select: none;
  font-size: 12px;
  height: 24px;
}

.pagination-control-wrapper:hover {
  background: rgba(64, 158, 255, 0.12);
  border-color: rgba(64, 158, 255, 0.3);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.15);
}

.page-count {
  font-size: 12px;
  font-weight: 500;
  color: #909399;
  line-height: 1;
}

.divider {
  width: 1px;
  height: 12px;
  background: rgba(64, 158, 255, 0.3);
  margin: 0 2px;
}

.pagination-info {
  font-size: 12px;
  font-weight: 500;
  color: #409eff;
  letter-spacing: 0.5px;
  min-width: 24px;
  text-align: center;
  line-height: 1;
}

.pagination-icon {
  font-size: 14px;
  color: #409eff;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  margin-left: 2px;
}

.pagination-icon.expanded {
  transform: rotate(180deg);
}

.table-container {
  width: 100%;
  overflow-x: visible;
  border-radius: 12px;
}

.enhanced-table {
  border-radius: 12px;
  overflow: hidden;
}

/* 确保表格头部不换行 - 参考 StarRocks Tables 实现 */
.enhanced-table :deep(.el-table__header-wrapper) th {
  font-size: 14px !important;
  font-weight: 500 !important;
  color: #606266 !important;
  white-space: nowrap !important;
}

/* 表格内容字体大小统一 */
.enhanced-table :deep(.el-table__body-wrapper) td {
  font-size: 14px !important;
}

/* 表格单元格样式 */
.cell-time {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #606266;
}

.cell-time .el-icon {
  color: #909399;
}

.slow-response {
  color: #f56c6c;
  font-weight: 600;
}

/* Element Plus表格自带tooltip功能，无需额外样式 */

/* 按钮自定义样式 - 与job页面一致 */
.search-btn {
  background: linear-gradient(135deg, #409EFF 0%, #66B3FF 100%);
  border: none;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.3);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  font-weight: 500;
}

.search-btn:hover {
  background: linear-gradient(135deg, #66B3FF 0%, #409EFF 100%);
  box-shadow: 0 6px 20px rgba(64, 158, 255, 0.4);
  transform: translateY(-2px);
}

.reset-btn {
  background: linear-gradient(135deg, #E6A23C 0%, #F0C78A 100%);
  border: none;
  border-radius: 8px;
  color: #fff;
  box-shadow: 0 4px 12px rgba(230, 162, 60, 0.3);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  font-weight: 500;
}

.reset-btn:hover {
  background: linear-gradient(135deg, #F0C78A 0%, #E6A23C 100%);
  box-shadow: 0 6px 20px rgba(230, 162, 60, 0.4);
  transform: translateY(-2px);
  color: #fff;
}

/* 确保表格单元格不换行 */
:deep(.el-table__cell) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 操作按钮样式 - 统一风格 */
.action-buttons {
  display: flex;
  gap: 8px;
  flex-wrap: nowrap;
  white-space: nowrap;
  justify-content: center;
  align-items: center;
  min-width: 60px;
}

.action-buttons .el-button {
  font-weight: 500;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
  width: 32px;
  height: 32px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.action-buttons .el-button:hover {
  transform: translateY(-2px) scale(1.05);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.action-buttons .el-button:active {
  transform: translateY(0) scale(0.98);
}

.action-buttons .el-button--primary {
  background: linear-gradient(135deg, #409EFF 0%, #66B3FF 100%);
  border: none;
}

/* 分页容器 */
.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

/* 详情弹窗 */
.log-detail {
  padding: 12px 0;
  max-height: 70vh;
  overflow-y: auto;
}

.log-detail :deep(.el-descriptions__label) {
  width: 120px;
  font-weight: 600;
  background-color: #f5f7fa;
}

.log-detail :deep(.el-descriptions__content) {
  min-width: 0;
}

.detail-text {
  word-break: break-all;
  white-space: pre-wrap;
  line-height: 1.6;
  max-height: 120px;
  overflow-y: auto;
  padding: 4px 0;
}

.detail-message {
  word-break: break-all;
  white-space: pre-wrap;
  line-height: 1.8;
  max-height: 300px;
  overflow-y: auto;
  padding: 8px;
  background-color: #f8f9fa;
  border-radius: 4px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 13px;
  color: #2c3e50;
}

/* JSON 字段单元格样式 */
.json-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}

.json-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.action-icons {
  display: flex;
  gap: 4px;
  flex-shrink: 0;
}

.copy-btn {
  flex-shrink: 0;
  padding: 4px 8px !important;
  opacity: 0.6;
  transition: opacity 0.2s;
}

.json-cell:hover .copy-btn {
  opacity: 1;
}

/* 详情中的 JSON 显示 */
.detail-json {
  position: relative;
}

.json-content {
  margin: 8px 0 0 0;
  padding: 12px;
  background-color: #f5f7fa;
  border-radius: 4px;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.6;
  max-height: 300px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

/* 字段设置面板样式 */
.field-selector-panel {
  margin-top: 20px;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 12px;
  border: 1px solid #e4e7ed;
}

.field-sorter {
  margin-bottom: 20px;
}

.sorter-header {
  margin-bottom: 16px;
}

.sorter-header h4 {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin: 0 0 8px 0;
}

.sorter-description {
  font-size: 13px;
  color: #909399;
  margin: 0;
}

.field-list-sortable {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 400px;
  overflow-y: auto;
}

.field-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  background: #fff;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  transition: all 0.3s ease;
}

.field-item:hover {
  border-color: #409EFF;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}

.field-item.field-disabled {
  background: #f5f7fa;
  opacity: 0.6;
}

.field-drag-handle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  color: #c0c4cc;
  cursor: move;
}

.drag-icon {
  font-size: 14px;
  font-weight: bold;
}

.field-checkbox {
  flex: 1;
  margin: 0;
}

.field-label {
  margin-left: 8px;
  font-size: 13px;
  color: #606266;
}

.required-mark {
  color: #f56c6c;
  margin-left: 4px;
  font-weight: bold;
}

.field-sort-controls {
  display: flex;
  gap: 4px;
  margin-left: 8px;
}

.field-sort-controls .el-button {
  width: 28px;
  height: 28px;
  padding: 0;
}

.field-actions {
  display: flex;
  justify-content: center;
  gap: 8px;
  padding: 16px;
  border-top: 1px solid #e4e7ed;
  background-color: #fafafa;
  margin-top: 16px;
  flex-wrap: wrap;
}

.field-actions .el-button {
  margin: 2px;
}

/* 字段面板动画 */
.field-panel-enter-active,
.field-panel-leave-active {
  transition: all 0.3s ease;
  overflow: hidden;
}

.field-panel-enter-from,
.field-panel-leave-to {
  opacity: 0;
  max-height: 0;
}

.field-panel-enter-to,
.field-panel-leave-from {
  opacity: 1;
  max-height: 800px;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .page-header {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .page-stats {
    width: 100%;
    flex-wrap: wrap;
  }
}

@media (max-width: 768px) {
  .log-list-container {
    padding: 16px;
  }
  
  .page-header {
    padding: 24px;
  }
  
  .page-stats {
    flex-wrap: wrap;
  }
  
  .stat-card {
    flex: 1 1 calc(50% - 10px);
    min-width: 150px;
  }
  
  .title-main h1 {
    font-size: 22px;
  }
  
  .title-meta {
    flex-wrap: wrap;
  }
  
  .search-form-fields {
    flex-direction: column;
  }
  
  .search-form-fields .el-form-item {
    margin-right: 0;
  }
}

@media (max-width: 480px) {
  .stat-card {
    flex: 1 1 100%;
  }
}

/* ===== 图片预览样式 ===== */
.image-preview-dialog {
  max-height: 85vh;
}

.image-preview-container {
  min-height: 400px;
  max-height: 55vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f5f7fa;
  border-radius: 8px;
  overflow: hidden;
}

.image-preview-container :deep(.el-image) {
  max-width: 100%;
  max-height: 100%;
}

.image-preview-container :deep(.el-image img) {
  max-width: 100%;
  max-height: 55vh;
  object-fit: contain;
}

.image-error {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 40px;
  color: #909399;
}

.error-icon {
  font-size: 64px;
  color: #c0c4cc;
}

.image-error p {
  margin: 0;
  font-size: 14px;
}

.error-url {
  font-size: 12px;
  color: #c0c4cc;
  word-break: break-all;
  max-width: 500px;
  text-align: center;
}

.image-preview-footer {
  display: flex;
  justify-content: center;
  gap: 12px;
}

/* 响应式图片预览 */
@media (max-width: 1200px) {
  .image-preview-dialog {
    width: 75% !important;
  }
  
  .image-preview-container {
    max-height: 50vh;
  }
  
  .image-preview-container :deep(.el-image img) {
    max-height: 50vh;
  }
}

@media (max-width: 768px) {
  .image-preview-dialog {
    width: 90% !important;
  }
  
  .image-preview-container {
    min-height: 300px;
    max-height: 45vh;
  }
  
  .image-preview-container :deep(.el-image img) {
    max-height: 45vh;
  }
}
</style>

<style>
/* 时间选择器弹出层优化（全局样式，不使用scoped） */
.datetime-picker-popper {
  z-index: 3000 !important;
}

.datetime-picker-popper .el-picker-panel__body {
  min-height: 380px;
}

.datetime-picker-popper .el-date-range-picker__time-header {
  position: relative;
  z-index: 1;
}

.datetime-picker-popper .el-picker-panel__content {
  margin: 0;
}

/* 确保时间选择面板不被日期面板遮挡 */
.datetime-picker-popper .el-time-panel {
  position: absolute;
  z-index: 2 !important;
  background: white;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

/* 优化日期时间范围选择器的布局 */
.datetime-picker-popper.el-popper {
  transform-origin: center top !important;
}
</style>
